package com.cd.university.config.security;

import com.cd.university.db.pojo.User;
import com.cd.university.service.PermissionService;
import com.cd.university.service.RoleService;
import com.cd.university.service.UserService;
import com.cd.university.vo.PermissionVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 陈栋
 * @create 2021/9/5 20:33
 */
public class DefaultUserDetailsService implements UserDetailsService {

    /**
     * 所有角色对应的权限列表
     */
    private List<PermissionVo> roleNameAndPerNameArrayList;

    /**
     * 日志输出
     */
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService permissionService;

    /**
     * 传入用户的信息（用户名，电话，邮件）查询用户
     * @param info 用户名，电话，邮件三者之一
     * @return UserDetails
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String info) throws UsernameNotFoundException {
        // 通过用户信息查询用户
        User userRepo = getUserRepo(info);

        if (userRepo==null) {
            throw new UsernameNotFoundException("用户不存在");
        }

        // 如果用户不为空,创建一个security的User对象
        return loadUser(userRepo);
    }

    /**
     * 拿到自定义的用户
     * @param info 用户信息
     * @return 用户实体类
     */
    public User getUserRepo(String info) {
        return userService.searchUserByUserInfo(info);
    }

    /**
     * 创建一个security的User对象
     * 对象中包括了用户名，角色以及密码
     * @param userRepo 自定义的用户类
     * @return security用户
     */
    private UserDetails loadUser(User userRepo) {
        // 查询数据库中用户的密码
        String password = userRepo.getPassword();

        // 根据用户的角色id查询角色对应的权限
        ArrayList<String> permissionList = searchPerNameByRoleId(userRepo.getRoleId());
        // 获得用户的角色名称
        String roleName = roleService.searchRoleName(userRepo.getRoleId());
        List<SimpleGrantedAuthority> permissions = new ArrayList<>();

        // 把查询得到的权限名称，加到SimpleGrantedAuthority的权限集合里面
        for (int i = 0; i < permissionList.size(); i++) {
            permissions.add(new SimpleGrantedAuthority(permissionList.get(i)));
        }

        // 添加用户的角色
        permissions.add(new SimpleGrantedAuthority(roleName));

        // new一个UserDetails的继承类User，放入用户名，密码，以及权限集合
        return new org.springframework.security.core.userdetails.User(userRepo.getUsername(),
                password,
                permissions);
    }

    /**
     * 通过角色id查询权限列表
     * 懒加载实现
     * @param roleId 角色id
     * @return 角色对应的权限列表
     */
    public ArrayList<String > searchPerNameByRoleId(Integer roleId) {
        if (roleNameAndPerNameArrayList==null) {
            // 查询所有的角色id对应的权限名称
            roleNameAndPerNameArrayList = permissionService.searchPermissionLeafByRoleId(roleId);
        }

        ArrayList<String > result = new ArrayList<>();
        for (PermissionVo permissionVo : roleNameAndPerNameArrayList) {
            result.add(permissionVo.getPermissionName());
        }
        return result;
    }
}
